#!/usr/bin/python
import qm
import re, operator
import sys

def creaSingleDataPathGraph(startPos, CellDict):
    def creaIndexSet(tabStr):
        i = 0
        tabStr = tabStr[::-1]
        oneList  = []
        zeroList = []
        for el in tabStr:
            if el == '1':
                oneList.append(i)
            else:
                zeroList.append(i)
            i += 1
        qmList = qm.qm(ones = oneList, zeros = zeroList)
        
        #print qmList
        
        funcList = [] 
        IndexSet = set()
        for minTerm in qmList:
            minTList = []
            for el,id in zip(minTerm,range(len(minTerm),0,-1)):
                if el == '0':
                    minTList.append("~A%d" % id)
                    IndexSet.add(id)
                elif el == '1':
                    minTList.append("A%d" % id)
                    IndexSet.add(id)
                    
            funcList.append('*'.join(minTList))
        
        #for id in range(1,5):
        #    if id not in IndexSet:
        #        funcList.append("A%d*0" % id)
              
        print "+".join(funcList)
        #print IndexSet
        return IndexSet
    
    DataPathGraph = []
    ProcessedCells = set()
    ProcessList = [startPos]
    while len(ProcessList)>0:
        curX, curY = ProcessList.pop()
        print "Analizzo nodo (%d, %d)" % (curX, curY)
        #if (curX, curY) in ProcessedCells:
        #    continue
        ProcessedCells.add((curX, curY))
        IndexSet = creaIndexSet(CellDict[curX][curY][0])
        IndexSet = IndexSet.union(creaIndexSet(CellDict[curX][curY][1]))
        
        print IndexSet
        #print ProcessedCells
        
        if curY % 2 == 0:
            baseOffset = 0
        else:
            baseOffset = 4	
        
        connList = []
        for index in IndexSet:
            nextY = index + baseOffset -1
            connList.append((curX-1, nextY))
            if curX>0:
                if (curX-1, nextY) not in ProcessedCells:
                        ProcessList.append((curX-1, nextY))
        
        DataPathGraph.append(((curX, curY), connList))
    
    return DataPathGraph, ProcessedCells

def creaDataPath(filePath, StartCells):
    
    
    def parseFile(filePath):
        #\s*=\s*\[(?P<LUTG>[01]{16})(?P<LUTF>[01]{16})\]
        indLineRE = re.compile("\((?P<X>\d+),(?P<Y>\d+)\)\s*=\s*\[(?P<LUTG>[01]{16})(?P<LUTF>[01]{16})\]")
        
        
        file = open(filePath,'r')
        if file==None:
            print "Impossibile aprire il file di Input per il parsing!"
            return None
        
        CellDict = {}
        for linea in file:
            #linea.strip('\r\n')
            match = indLineRE.search(linea)
            if match == None:
                print "No match: %s" % linea
                continue
            #, match.group(LUTG), match.group(LUTF)
            #print "[%d,%d] G=[%s] F=[%s]" % (int(match.group('X')), int(match.group('Y')), match.group('LUTG'), match.group('LUTF'))
            X = int(match.group('X'))
            Y = int(match.group('Y'))
            if X not in CellDict:
                CellDict[X] = {}
            CellDict[X][Y] = (match.group('LUTG'), match.group('LUTF'))
            
        file.close()
        return CellDict
    
    CellDict = parseFile(filePath)
    if CellDict == None:
        return
    
    #print CellDict
    #UsedCells = set()
    for X0, Y0 in StartCells:
        #UsedCells.add((X0,Y0))
        dataGraph, UsedCells = creaSingleDataPathGraph((int(X0),int(Y0)), CellDict)
        dataGraph.sort(key = operator.itemgetter(0))
        
        #UsedCells = list(UsedCells)
        #UsedCells.sort()
        for cell in dataGraph:
            print cell
        
        print "-"*60
        
        
    #self.CheckWordDict = {}
    #XCoords = CellDict.keys()
    #XCoords.sort()
    #for Xk in XCoords:
    #    YCoords = CellDict[Xk].keys()
    #    YCoords.sort()
    #    for Yk in YCoords:
    #        LUTVal =  "G:#LUT:D=(%s) F:#LUT:D=(%s)" % (creaExp(CellDict[Xk][Yk][0]), creaExp(CellDict[Xk][Yk][1]))
            

def main():
    if len(sys.argv)<3:
        print """Utilizzo:\ndataPathCheck.py genoFile "(X,Y)[;(X,Y)]*" """
        return 
    cellStartList = sys.argv[2].split(';')
    cellStartList = map(lambda x: x.strip('() ').split(','), cellStartList)
    #print cellStartList
    creaDataPath(sys.argv[1], cellStartList)
    
if __name__ == "__main__":
    main()
